#!/usr/bin/python3
import os
from .Entity_Field import Entity_Field


from utils import My_Util2, String_Util


class Entity:
    """
    实体模型
    """

    def __init__(
        self, context, author, package: str, table_name: str, comment: str
    ) -> None:
        self.context = context
        self.author = author
        self.package = package
        self.table_name = table_name
        self.name = String_Util.entity_name(self.table_name)
        self.comment = String_Util.check_comment_symbol(comment)
        self.fields: list[Entity_Field] = list()
        self.prefix = self.table_name.split("_")[0].lower()
        self.sort_number = False
        self.my_util2 = My_Util2.My_Util(self.context)

    def has_sort(self):
        for field in self.fields:
            if field.ignore():
                continue
            if field.is_sort():
                return True
        return False

    def has_status(self):
        for field in self.fields:
            if field.ignore():
                continue
            if field.is_status():
                return True
        return False

    def has_single_verify(self):
        for field in self.fields:
            if field.ignore():
                continue
            if field.is_single_verify():
                return True
        return False

    def code_includes(self):
        framework_package = f"""{self.context['package']}.{self.context['framework_package']}"""
        package = self.package
        i18n = False
        currency = False
        decimal = False
        date = False
        not_null = False
        local_date_time = False
        for field in self.fields:
            if field.ignore():
                continue
            if field.i18n:
                i18n = True
            if field.currency:
                currency = True
            if field.java_type == "BigDecimal":
                decimal = True
            if field.java_type == "Date":
                date = True
            if field.java_type == "LocalDateTime":
                local_date_time = True
            if field.required():
                not_null = True

        includes = list()

        if i18n or currency:
            includes.append(
                f"""import com.baomidou.mybatisplus.annotation.TableField;"""
            )
        includes.append(f"""import com.baomidou.mybatisplus.annotation.TableName;""")
        includes.append(f"""import {framework_package}.support.entity.BaseEntity;""")
        if i18n:
            includes.append(f"""import {package}.internal.i18n.NameInfo;""")
            includes.append(f"""import {package}.internal.i18n.NameTypeHandler;""")
        if currency:
            includes.append(f"""import {package}.internal.currency.Currency;""")
            includes.append(f"""import {package}.internal.currency.CurrencyTypeHandler;""")
        includes.append(f"""import lombok.Data;""")
        includes.append(f"""import lombok.EqualsAndHashCode;""")
        includes.append(f"""import lombok.ToString;""")
        if not_null:
            includes.append("import jakarta.validation.constraints.NotNull;")
        if decimal:
            includes.append("import java.math.BigDecimal;")
        if date:
            includes.append("import java.util.Date;")
        if local_date_time:
            includes.append("import java.time.LocalDateTime;")
        includes = self.my_util2.sort_import_order(includes)
        includes = "\r".join(includes)
        return includes

    def code_fields(self):
        field_code = list()
        for field in self.fields:
            if field.ignore():
                continue
            required = (
                f"""
    @NotNull"""
                if field.required()
                else ""
            )
            code = field.code(openapi=False)
            comment = f"""
    /**
     * {field.comment}
     */"""
            if "private NameInfo" in code:
                table_field = f"""
    @TableField(typeHandler = NameTypeHandler.class)"""
            elif "private Currency" in code:
                table_field = f"""
    @TableField(typeHandler = CurrencyTypeHandler.class)"""
            else:
                table_field = ""
            code = f"""{comment}{table_field}{required}
    {code}"""
            field_code.append(code)
        field_code = "\r".join(field_code)
        return field_code

    def save_file(self, dir):
        _target_dir = os.path.join(dir, self.context["code_storage"]["root"], "entity")
        if not os.path.exists(_target_dir):
            os.makedirs(_target_dir)
        with open(
            os.path.join(_target_dir, "{}.java".format(self.name)),
            mode="w",
            encoding="utf-8",
        ) as f:
            f.write(self.code())

    def add_fields(self, fields: list):
        self.fields.extend(fields)
        for field in fields:
            if "sort_number" == field.column_name:
                self.sort_number = True

    def code(self):
        author = self.author
        package = self.package
        prefix = self.prefix
        table_name = self.table_name.lower()
        name = self.name
        comment = self.comment

        includes = self.code_includes()

        fields = self.code_fields()

        return f"""package {package}.{self.context["code_storage"]["root"]}.entity;

{includes}

/**
 * <p>
 * {comment}
 * </p>
 *
 * @author {author}
 */
@EqualsAndHashCode(callSuper = true)
@Data
@ToString(callSuper = true)
@TableName(value = "{table_name}", autoResultMap = true)
public class {name} extends BaseEntity {"{"}
{fields if len(fields) > 0 else ''}
{"}"}
"""
